package com.wdb007.venus.svc.biz.wxapp;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.wdb007.venus.svc.biz.utils.DateFormatUtil;
import com.wdb007.venus.svc.biz.utils.DateUtil;
import com.wdb007.venus.svc.dal.account.dao.AccountCashDAO;
import com.wdb007.venus.svc.dal.account.dao.AccountCashLogDAO;
import com.wdb007.venus.svc.dal.account.model.AccountCashDO;
import com.wdb007.venus.svc.dal.account.model.AccountCashLogDO;
import com.wdb007.venus.svc.dal.order.dao.OrderTransDAO;
import com.wdb007.venus.svc.dal.user.dao.UserCostFlagDAO;
import com.wdb007.venus.svc.dal.user.dao.UserInfoDAO;
import com.wdb007.venus.svc.dal.user.dao.UserReadStatisticsDAO;
import com.wdb007.venus.svc.dal.user.model.UserCostFlagDO;
import com.wdb007.venus.svc.dal.user.model.UserInfoDO;
import com.wdb007.venus.svc.dal.user.model.UserReadStatisticsDO;
import com.wdb007.venus.svc.dal.vip.dao.VipMemberDAO;
import com.wdb007.venus.svc.dal.vip.dao.VipMemberLogDAO;
import com.wdb007.venus.svc.dal.vip.model.VipMemberDO;
import com.wdb007.venus.svc.dal.vip.model.VipMemberLogDO;
import com.wdb007.venus.svc.facade.UserCostFlagService;
import com.wdb007.venus.svc.facade.VipMemberService;
import com.wdb007.venus.svc.facade.WxAPPMessagePushService;
import com.wdb007.venus.svc.facade.WxAppHDService;
import com.wdb007.venus.svc.facade.account.model.UserCostFlagDTO;
import com.wdb007.venus.svc.facade.account.model.VipMemberLogDTO;
import com.wdb007.venus.svc.facade.constant.BizConstants;
import com.wdb007.venus.svc.facade.constant.RspCodeEnum;
import com.wdb007.venus.svc.facade.exception.BizException;
import com.wdb007.venus.svc.facade.wxapp.model.MutilReadRecordDTO;
import com.wdb007.venus.svc.facade.wxapp.model.SingleReadRecordDTO;

@Service("wxAppHDService")
public class WxAppHDServiceImpl implements WxAppHDService {

	private final static Logger logger = LoggerFactory.getLogger(WxAppHDServiceImpl.class);

	@Autowired
	private UserInfoDAO userInfoDAO;
	@Autowired
	private OrderTransDAO orderTransDAO;
	@Autowired
	private AccountCashDAO accountCashDAO;
	@Autowired
	private AccountCashLogDAO accountCashLogDAO;
	@Autowired
	private VipMemberDAO vipMemberDAO;
	@Autowired
	private VipMemberLogDAO vipMemberLogDAO;
	@Autowired
	private UserCostFlagDAO userCostFlagDAO;
	
	@Autowired
	private WxAPPMessagePushService wxAPPMessagePushService;
	@Autowired
	private UserReadStatisticsDAO userReadStatisticsDAO;
	@Autowired
	private VipMemberService vipMemberService;
	@Autowired
	private UserCostFlagService userCostFlagService;
	
	@Override
	public SingleReadRecordDTO getSingleUserReadRecord(Long userId) throws BizException {
		SingleReadRecordDTO record = new SingleReadRecordDTO();
		UserReadStatisticsDO ursDO = userReadStatisticsDAO.getByUserId(userId);
		UserReadStatisticsDO totalRecord = userReadStatisticsDAO.getUserTotalRecordFromOrderTrans(userId);
		UserReadStatisticsDO monthRecord = userReadStatisticsDAO.getUserMonthRecordFromOrderTrans(userId);
		UserReadStatisticsDO weekRecord = userReadStatisticsDAO.getUserWeekRecordFromOrderTrans(userId);
		if(null == ursDO && totalRecord != null) {
			if(null != weekRecord) {
				totalRecord.setWeekCount(weekRecord.getWeekCount());
				totalRecord.setWeekCumulativeTime(weekRecord.getWeekCumulativeTime());
			}
			if(null != monthRecord) {
				totalRecord.setMonthCount(monthRecord.getMonthCount());
				totalRecord.setMonthCumulativeTime(monthRecord.getMonthCumulativeTime());
			}
			
			totalRecord.setUserId(userId);
			totalRecord.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			totalRecord.setCreateTime(new Date());
			userReadStatisticsDAO.insert(totalRecord);
		}else if(null != ursDO) {
			ursDO.setTotalCount(totalRecord.getTotalCount());
			ursDO.setTotalCumulativeTime(totalRecord.getTotalCumulativeTime());
			if(null != weekRecord) {
				ursDO.setWeekCount(weekRecord.getWeekCount());
				ursDO.setWeekCumulativeTime(weekRecord.getWeekCumulativeTime());
			}
			if(null != monthRecord) {
				ursDO.setMonthCount(monthRecord.getMonthCount());
				ursDO.setMonthCumulativeTime(monthRecord.getMonthCumulativeTime());
			}
			ursDO.setModifyTime(new Date());
			userReadStatisticsDAO.update(ursDO);
		}else {
			record.setMonth_record(0);
			record.setWeek_record(0);
			record.setTotal_record(0);
			record.setUserid(userId);
			return record;
		}
		if(null != monthRecord) {
			record.setMonth_record(monthRecord.getMonthCount() == null ? 0 : monthRecord.getMonthCount());
		}else {
			record.setMonth_record(0);
		}
		if(null != weekRecord) {
			record.setWeek_record(weekRecord.getWeekCount() == null ? 0 : weekRecord.getWeekCount());
		}else {
			record.setWeek_record(0);
		}
		if(null != totalRecord) {
			record.setTotal_record(totalRecord.getTotalCount() == null ? 0 : totalRecord.getTotalCount());
		}
		
		record.setUserid(userId);
		return record;
	}

	@Override
	public List<MutilReadRecordDTO> getMutliUserReadRecord() throws BizException {
		List<MutilReadRecordDTO> list = new ArrayList<MutilReadRecordDTO>();
		List<UserReadStatisticsDO> ursList = userReadStatisticsDAO.list();
		for(UserReadStatisticsDO ursDO : ursList) {
			MutilReadRecordDTO mrrDTO = new MutilReadRecordDTO();
			SingleReadRecordDTO srrDTO = new SingleReadRecordDTO();
			srrDTO.setMonth_record(ursDO.getMonthCount() == null ? 0 : ursDO.getMonthCount());
			srrDTO.setTotal_record(ursDO.getTotalCount() == null ? 0 : ursDO.getTotalCount());
			srrDTO.setWeek_record(ursDO.getWeekCount() == null ? 0 : ursDO.getWeekCount());
			srrDTO.setUserid(ursDO.getUserId());
			mrrDTO.setRecord(srrDTO);
			mrrDTO.setUserid(ursDO.getUserId());
			list.add(mrrDTO);
		}
		return list;
	}

	@Override
	public void presentVIP(String mobile_no, String vip_type) throws BizException {
		UserInfoDO userInfo = userInfoDAO.getByMobileNo(mobile_no);
		if (null == userInfo) {
			throw new BizException(RspCodeEnum.USER_NOT_FOUND);
		}
		VipMemberDO vipMember = vipMemberDAO.getByUserId(userInfo.getId());
		Integer vipType = Integer.valueOf(vip_type);
		if(null == vipMember){
			vipMember = new VipMemberDO();
			vipMember.setCreateTime(new Date());
			vipMember.setStartTime(new Date());
			vipMember.setUserId(userInfo.getId());
			vipMember.setVipType(vipType);
			vipMember.setValidFlag(1);
			if(1 == vipType){
				vipMember.setRemainMonth(new BigDecimal("1"));
				vipMember.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextMouth(new Date())));
			}else if(2 == vipType){
				vipMember.setRemainMonth(new BigDecimal("12"));
				vipMember.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextYear(new Date())));
			}
			vipMemberDAO.save(vipMember);
		}else{
			vipMember.setVipType(vipType);
			vipMember.setModifyTime(new Date());
			vipMember.setUserId(userInfo.getId());
			if(1 == vipType){
				vipMember.setRemainMonth(vipMember.getRemainMonth().add(new BigDecimal("1.00")));
				vipMember.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextMouth(vipMember.getEndTime())));
			}else if(2 == vipType){
				vipMember.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextYear(vipMember.getEndTime())));
				vipMember.setRemainMonth(vipMember.getRemainMonth().add(new BigDecimal("12.00")));
			}
			vipMemberDAO.update(vipMember);
		}
		VipMemberLogDO vipMemberLogDO = new VipMemberLogDO();
		vipMemberLogDO.setCreateTime(new Date());
		vipMemberLogDO.setUserId(userInfo.getId());
		vipMemberLogDO.setVipType(Integer.valueOf(vip_type));
		if("1".equals(vip_type)){
			vipMemberLogDO.setVipAmount(new BigDecimal("38.00"));
		}else if("2".equals(vip_type)){
			vipMemberLogDO.setVipAmount(new BigDecimal("365.00"));
		}
		vipMemberLogDO.setChargeType(20);
		vipMemberLogDAO.save(vipMemberLogDO);
		
		UserCostFlagDO query = new UserCostFlagDO();
		query.setUserId(userInfo.getId());
		query.setValidFlag(1);
		if(1 == vipType){
			query.setFlag(3);
			UserCostFlagDO result = userCostFlagDAO.getByCondition(query);
			if(result == null) {
				//判断是否有年卡，如果有年卡，则直接在年卡的基础上加一个月。
				UserCostFlagDO query2 = new UserCostFlagDO();
				query2.setUserId(userInfo.getId());
				query2.setValidFlag(1);
				query2.setFlag(4);
				UserCostFlagDO result2 = userCostFlagDAO.getByCondition(query2);
				Date startTime = new Date();
				if(null != result2) {
					startTime = DateFormatUtil.getMaxTimeDay(result2.getEndTime());
				}
				query.setCostOrder(3);
				query.setCreateTime(new Date());
				query.setValidFlag(BizConstants.USER_COST_FLAG_VALIDFLAG_1);
				query.setStartTime(startTime);
				query.setRemainder(new BigDecimal("38"));
				query.setPrice(new BigDecimal("0.00"));
				query.setEndTime(DateUtil.getNextMouth(startTime));
				userCostFlagDAO.insert(query);
			}else {
				result.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextMouth(result.getEndTime())));
				result.setModifyTime(new Date());
				userCostFlagDAO.update(result);
				query.setEndTime(DateFormatUtil.getMaxTimeDay(result.getEndTime()));//推送需要endtime

			}
		}else if(2 == vipType){
			query.setFlag(4);
			UserCostFlagDO result = userCostFlagDAO.getByCondition(query);
			//判断是否有月卡，如果有，则调整月卡的有效起始时间。
			UserCostFlagDO query2 = new UserCostFlagDO();
			query2.setUserId(userInfo.getId());
			query2.setFlag(3);
			UserCostFlagDO result2 = userCostFlagDAO.getByCondition(query2);
			if(null != result2) {
				result2.setStartTime(DateUtil.getNextYear(result2.getStartTime()));
				result2.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextYear(result2.getEndTime())));
				result2.setModifyTime(new Date());
				userCostFlagDAO.update(result2);
				
				query.setEndTime(DateFormatUtil.getMaxTimeDay(result2.getEndTime()));//推送需要endtime
			}
			if(result == null) {
				query.setCostOrder(4);
				query.setCreateTime(new Date());
				query.setValidFlag(BizConstants.USER_COST_FLAG_VALIDFLAG_1);
				query.setStartTime(new Date());
				query.setRemainder(new BigDecimal("365"));
				query.setPrice(new BigDecimal("0.00"));
				query.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextYear(new Date())));
				userCostFlagDAO.insert(query);
			}else {
				result.setEndTime(DateFormatUtil.getMaxTimeDay(DateUtil.getNextYear(result.getEndTime())));
				userCostFlagDAO.update(result);
			}
		}
		//活动赠送
		try {
			wxAPPMessagePushService.sendVipCardToAccountNotice(vipType, new BigDecimal("0.00"), DateFormatUtil.formatDate2(new Date()), userInfo.getId(), DateFormatUtil.formatDate2(query.getEndTime()), BizConstants.VIP_CHARGE_TYPE_20);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void presentAmount(String mobile_no, String amount) throws BizException {
		UserInfoDO userInfo = userInfoDAO.getByMobileNo(mobile_no);
		if (null == userInfo) {
			throw new BizException(RspCodeEnum.USER_NOT_FOUND);
		}

		AccountCashDO accountCash = accountCashDAO.getByUserid(userInfo.getId());
		BigDecimal addAmount = new BigDecimal(amount).divide(new BigDecimal("100"));

		AccountCashLogDO accountCashLogDO = new AccountCashLogDO();
		accountCashLogDO.setAccountCashId(accountCash.getId());
		accountCashLogDO.setChangeAmount(addAmount);
		accountCashLogDO.setChargeType(90);
		accountCashLogDO.setCreateTime(new Date());
		accountCashLogDO.setOperType(10);
		accountCashLogDAO.insert(accountCashLogDO);

		accountCash.setCashAmount(accountCash.getCashAmount().add(addAmount));
		accountCash.setModifyTime(new Date());
		accountCashDAO.update(accountCash);
		
		//活动赠送，小程序服务消息发送
		try {
			wxAPPMessagePushService.sendRechangeToAccountNotice(userInfo.getMobileNo(), BizConstants.ACCOUNT_CASH_CHARGE_TYPE_30, new Date(), addAmount, userInfo.getId());
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void presentVIP(String mobileNo, Integer vipType, Integer days) throws BizException {
		if(BizConstants.VIP_TYPE_3 != vipType) {
			presentVIP(mobileNo, vipType+"");
		}else {
			Long userId = userInfoDAO.getByMobileNo(mobileNo).getId();
			//更新用户月卡信息
			VipMemberLogDTO vipMemberLogDTO = new VipMemberLogDTO();
			vipMemberLogDTO.setChargeType(BizConstants.VIP_CHARGE_TYPE_30);
			vipMemberLogDTO.setDays(days);
			vipMemberLogDTO.setUserId(userId);
			vipMemberLogDTO.setVipType(1);
			vipMemberService.saveVipMember(vipMemberLogDTO);
			//更新用户扣费标准信息
			UserCostFlagDTO userCostFlagDTO = new UserCostFlagDTO();
			userCostFlagDTO.setDays(days);
			userCostFlagDTO.setFlag(3);
			userCostFlagDTO.setUserId(userId);
			userCostFlagService.saveUserCostFlag(userCostFlagDTO);
			
		}
		
	}

}
